{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Fuzzy K-means"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一种基于划分的聚类算法，其思想就是使得被划分到同一簇的对象之间相似度最大，而不同簇之间的相似度最小。模糊K均值算法是普通K均值算法的改进，普通K均值算法对于数据的划分是硬性的，而模糊K均值则是一种柔性的模糊划分。\n",
    "\n",
    "**隶属度**：隶属度表示一个对象 $x$属于集合 $A$的程度的函数，取值范围为$[0,1]$，对于有 $M$个样本数据的数据集 $T$，若其可以分为 $C$类，则隶属度矩阵可以表示为一个 $C\\times M$的矩阵 $\\bold U$。\n",
    "$$\n",
    "\\bold U=\n",
    "\\left[\n",
    "    \\begin{array}{cccc}\n",
    "    u_{11}&u_{12}&\\cdots&u_{1M}\\\\\n",
    "    u_{21}&u_{22}&\\cdots&u_{2M}\\\\\n",
    "    \\vdots&\\vdots&\\ddots&\\vdots\\\\\n",
    "    u_{C1}&u_{C2}&\\cdots&u_{CM}\\\\\n",
    "    \\end{array}\n",
    "\\right]\n",
    "$$\n",
    "且有 $\\bold U$的每一列元素加起来和为1。而其中元素 $u_{ij},i=1,\\cdots,C;j=1,\\cdots,M$表示样本 $\\boldsymbol x_j$属于类 $c_i$的隶属度，且其值的范围为$[0,1]$。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "选取$C$个聚类中心，模糊K均值的目标函数为\n",
    "$$\n",
    "J=\\sum_{i=1}^C\\sum_{j=1}^M u_{ij}^m||\\boldsymbol x_j-\\boldsymbol c_i||^2\n",
    "\\tag{1}\n",
    "$$\n",
    "其约束条件为\n",
    "$$\n",
    "\\sum_{i=1}^C u_{ij}=1,j=1,\\cdots,M\n",
    "\\tag{2}\n",
    "$$\n",
    "其中 $m$为模糊器，又称为加权指数，有研究表明，当 $m\\in [1.5,2.5]$时效果较好。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "先构造拉格朗日函数\n",
    "$$\n",
    "L=\\sum_{i=1}^C\\sum_{j=1}^M u_{ij}^m||\\boldsymbol x_j-\\boldsymbol c_i||^2+\\sum_{j=1}^M\\lambda_j(\\sum_{i=1}^C u_{ij}-1)\n",
    "\\tag{3}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将上述函数对 $u_{ij}$求导，并将求导的结果置为0\n",
    "$$\n",
    "\\frac{\\partial L}{\\partial u_{ij}}=m u_{ij}^{m-1}||\\boldsymbol x_j-\\boldsymbol c_i||^2+\\lambda_j=0\n",
    "\\tag{4}\n",
    "$$\n",
    "得到\n",
    "$$\n",
    "u_{ij}^{m-1}=-\\frac{1}{m}\\frac{\\lambda_j}{||\\boldsymbol x_j-\\boldsymbol c_i||^2}\n",
    "\\tag{5}\n",
    "$$\n",
    "即可解得 $u_{ij}$\n",
    "$$\n",
    "u_{ij}=(-\\frac{\\lambda_j}{m})^{\\frac{1}{m-1}}\\frac{1}{(\\boldsymbol x_j-\\boldsymbol c_i)^{\\frac{2}{m-1}}}\n",
    "\\tag{6}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "联立式子2和6可得\n",
    "$$\n",
    "\\sum_{i=1}^Cu_{ij}=(-\\frac{\\lambda_j}{m})^{\\frac{1}{m-1}}\\sum_{i=1}^C\\frac{1}{(\\boldsymbol x_j-\\boldsymbol c_i)^{\\frac{2}{m-1}}}=1\n",
    "\\tag{7}\n",
    "$$\n",
    "解得\n",
    "$$\n",
    "(-\\frac{\\lambda_j}{m})^{\\frac{1}{m-1}}=\\frac{1}{\\sum_{i=1}^C\\frac{1}{(\\boldsymbol x_j-\\boldsymbol c_i)^{\\frac{2}{m-1}}}}\n",
    "\\tag{8}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将式子8代入式子6中可得\n",
    "$$\n",
    "\\begin{aligned}\n",
    "u_{ij}\n",
    "&=\\frac{1}{\\sum_{i=1}^C\\frac{1}{(\\boldsymbol x_j-\\boldsymbol c_i)^{\\frac{2}{m-1}}}}\\frac{1}{(\\boldsymbol x_j-\\boldsymbol c_i)^{\\frac{2}{m-1}}}\\\\\n",
    "&=\\frac{1}\n",
    "    {\n",
    "    \\sum_{i=1}^C(\\frac{(\\boldsymbol x_j-\\boldsymbol c_k)^{\\frac{2}{m-1}}}{(\\boldsymbol x_j-\\boldsymbol c_i)^{\\frac{2}{m-1}}})\n",
    "    }\\\\\n",
    "&=\\frac{1}{\\sum_{i=1}^C(\\frac{\\boldsymbol x_j-\\boldsymbol c_k}{\\boldsymbol x_j-\\boldsymbol c_i})^{\\frac{2}{m-1}}}\n",
    "\\end{aligned}\n",
    "\\tag{9}\n",
    "$$\n",
    "这里需要注意的是，$\\boldsymbol c_k$相对于 $\\boldsymbol c_i$来说是固定的。上式9即得到的隶属度的更新式子。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后求解聚类中心的更新式子，先求解 $\\frac{\\partial J}{\\partial \\boldsymbol c_i}$，并置为0\n",
    "$$\n",
    "\\frac{\\partial L}{\\partial \\boldsymbol c_i}=\\sum_{j=1}^M(-u_{ij}^m2(\\boldsymbol x_j-\\boldsymbol c_i))=0\n",
    "\\tag{10}\n",
    "$$\n",
    "解得\n",
    "$$\n",
    "\\boldsymbol c_i=\\frac{\\sum_{j=1}^Mu_{ij}^m\\boldsymbol x_j}{\\sum_{j=1}^Mu_{ij}^m}\n",
    "\\tag{11}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最终整理得\n",
    "$$\n",
    "\\left\\{\\begin{aligned}\n",
    "    u_{ij}&=\\frac{1}{\\sum_{i=1}^C(\\frac{\\boldsymbol x_j-\\boldsymbol c_k}{\\boldsymbol x_j-\\boldsymbol c_i})^{\\frac{2}{m-1}}}\\\\\n",
    "    \\boldsymbol c_i&=\\frac{\\sum_{j=1}^Mu_{ij}^m\\boldsymbol x_j}{\\sum_{j=1}^Mu_{ij}^m}\n",
    "\\end{aligned}\n",
    "\\right.\n",
    "\\tag{12}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "模糊K均值算法步骤为\n",
    "\n",
    "输入：聚类数 $C$、加权指数$m$、迭代停止条件、初始化隶属度矩阵$\\boldsymbol U$\n",
    "1. 根据 $\\boldsymbol U$计算聚类中心\n",
    "2. 计算目标函数 $J$\n",
    "3. 根据聚类中心计算 $\\boldsymbol U$\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 参考"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[模糊K均值](https://blog.csdn.net/weixin_39653948/article/details/117575762)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 代码"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 自定义函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 生成初始化隶属度矩阵 $\\boldsymbol U$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化隶属度矩阵 U\n",
    "def init_fuzzy_matrix(C, n_sample):\n",
    "    \"\"\"\n",
    "    初始化隶属度矩阵，注意列和为1\n",
    "    ----\n",
    "    param n_sample: 样本数量\n",
    "    param C: 聚类数量\n",
    "    \"\"\"\n",
    "    # 针对数据集中所有样本的隶属度矩阵，shape = [C, n_samples]\n",
    "    # 先生成一个形状一样的，元素值为0-10之间随机数的矩阵\n",
    "    fuzzy_matrix = np.random.randint(10,size=(C,n_sample))  \n",
    "\n",
    "    # 计算每列的和\n",
    "    column_sum=np.sum(fuzzy_matrix,axis=0)\n",
    "    # 使得每列之和为1\n",
    "    fuzzy_matrix=fuzzy_matrix/column_sum\n",
    "\n",
    "    return fuzzy_matrix\n",
    "\n",
    "# m=init_fuzzy_matrix(3,150)\n",
    "# print(np.sum(m,axis=0))     #检验每列之和\n",
    "# print(m)\n",
    "\n",
    "# fuzzy_matrix=init_fuzzy_matrix(3,150)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 计算聚类中心"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算聚类中心\n",
    "def cluster_centers(X,fuzzy_matrix,m):\n",
    "    \"\"\"\n",
    "    param X: 数据集的特征集\n",
    "    param fuzzy_matrix: 隶属度矩阵\n",
    "    param m: 加权指数\n",
    "    \"\"\"\n",
    "\n",
    "# denominator-分母\n",
    "# molecular-分子\n",
    "\n",
    "    # 式子12中求聚类中心的分母\n",
    "    molecular=np.dot(fuzzy_matrix**m,X)\n",
    "    # print(molecular)\n",
    "    # 式子12中求聚类中心的分子\n",
    "    denominator=np.sum(fuzzy_matrix**m,axis=1)\n",
    "    # print(denominator)\n",
    "    # 分子的每一个元素都要除分母中的每一个行中的元素\n",
    "    # 反正就是分母数组要变成每行一个元素的样子，再利用numpy的广播机制。\n",
    "    c=molecular/(denominator.reshape(-1,1))\n",
    "\n",
    "    return c\n",
    "\n",
    "# # 检验\n",
    "# f=np.array([[0.9,0.8,0.7,0.1],[0.1,0.2,0.3,0.9]])\n",
    "# X=np.array([[0,0],[0,1],[3,1],[3,2]])\n",
    "# 此时计算出来的 c=[[0.77,0.59],[2.84,1.84]]。验证看对不对\n",
    "# c=cluster_centers(X=X,fuzzy_matrix=f,m=2)\n",
    "# print(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 更新隶属度矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def update_fuzzy_matrix(X,c,m=2):\n",
    "    \"\"\"\n",
    "    param X: 数据集的特征集\n",
    "    param c:聚类中心矩阵\n",
    "    param m: 加权指数\n",
    "    \"\"\"\n",
    "    # 式子12中更新隶属度式子的指数\n",
    "    exponential = 1.0/(m-1)\n",
    "    # 式子12中更新隶属度式子分母求和中的分母\n",
    "    # 针对某个隶属度u_ij，分式项表示，某个样本j到某个聚类中心i的距离与这个样本到所有聚类中心距离的比值\n",
    "    # 先计算样本j到各个聚类中心的距离矩阵\n",
    "    C,_=c.shape\n",
    "    n_sample,_=X.shape\n",
    "\n",
    "    # 创建两个与隶属度矩阵一样大小的临时矩阵\n",
    "    temp_matrix=np.ones((C,n_sample))\n",
    "    fuzzy_matrix=np.ones_like(temp_matrix)\n",
    "\n",
    "\n",
    "    # 遍历每个样本\n",
    "    for i,x in enumerate(X):\n",
    "        single_matrix=np.sum((c-x)**2,axis=1)\n",
    "        # fraction项\n",
    "        temp_matrix[:,i]=single_matrix.reshape(-1,1).ravel()\n",
    "    # print(temp_matrix)\n",
    "    for row in range(C):\n",
    "        for column in range(n_sample):\n",
    "            fuzzy_matrix[row,column]=1.0/np.sum(temp_matrix[row,column]/temp_matrix[:,column])\n",
    "    # print(fuzzy_matrix**exponential)\n",
    "\n",
    "    return fuzzy_matrix**exponential\n",
    "# # 用于检验的数据\n",
    "# X=np.array([[0,0],[0,1],[3,1],[3,2]])\n",
    "# c=np.array([[0.77,0.59],[2.84,1.84]])\n",
    "# 若成功，则新的隶属度矩阵应该为 [[0.92406514 0.92016533 0.12451892 0.00730156],[0.07593486 0.07983467 0.87548108 0.99269844]]\n",
    "# fm=update_fuzzy_matrix(X=X,c=c)\n",
    "# print(fm)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 迭代训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "隶属度矩阵初始化完成：shape= (2, 4)\n",
      "满足条件，返回新的聚类中心和新的隶属度矩阵\n",
      "[[0.53385925 0.51854035 0.48146325 0.46620681]\n",
      " [0.46614075 0.48145965 0.51853675 0.53379319]]\n",
      "[[1. 1. 0. 0.]\n",
      " [0. 0. 1. 1.]]\n"
     ]
    }
   ],
   "source": [
    "from copy import deepcopy\n",
    "# 定义训练函数\n",
    "def fuzzy_k_means(X,C,epsilon=0.1,iter_num=10,m=2):\n",
    "    \"\"\"\n",
    "    param X: 数据集的特征集\n",
    "    param C:聚类中心数量\n",
    "    param epsilon: 训练终止条件\n",
    "    param iter_num: 迭代次数设定\n",
    "    param m: 加权指数\n",
    "    \"\"\"\n",
    "    n_sample,_=X.shape\n",
    "\n",
    "     # 初始化隶属度矩阵\n",
    "    fuzzy_matrix=init_fuzzy_matrix(n_sample=n_sample,C=C)\n",
    "    print(\"隶属度矩阵初始化完成：shape=\",fuzzy_matrix.shape)\n",
    "\n",
    "    # 开始训练\n",
    "    count=1\n",
    "    while count<=iter_num:\n",
    "        # 每次都要先记录一下隶属度矩阵，这里需要深拷贝\n",
    "        remember_fuzzy_matrix=deepcopy(fuzzy_matrix)\n",
    "        # 计算聚类中心\n",
    "        c=cluster_centers(X=X,fuzzy_matrix=fuzzy_matrix,m=m)\n",
    "\n",
    "        # 更新隶属度矩阵\n",
    "        fuzzy_matrix=update_fuzzy_matrix(X=X,c=c,m=m)\n",
    "\n",
    "        # 判断终止条件\n",
    "        if np.max(fuzzy_matrix-remember_fuzzy_matrix)<epsilon:\n",
    "            print(\"满足条件，返回新的聚类中心和新的隶属度矩阵\")\n",
    "            return (c,fuzzy_matrix)\n",
    "\n",
    "        count+=1\n",
    "\n",
    "    print(\"达到迭代次数，返回新的聚类中心和新的隶属度矩阵\")\n",
    "    return (c,fuzzy_matrix)\n",
    "\n",
    "\n",
    "X=np.array([[0,0],[0,1],[3,1],[3,2]])\n",
    "C=2\n",
    "\n",
    "c,fuzzy_matrix=fuzzy_k_means(X=X,C=C,epsilon=0.1,iter_num=5)   \n",
    "print(fuzzy_matrix)\n",
    "# 根据隶属度矩阵，将每列的最大值设为1，其余设为0\n",
    "classification_matrix=(fuzzy_matrix == fuzzy_matrix.max(axis=0, keepdims=0)).astype(float)\n",
    "print(classification_matrix)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据集：shape (150, 2)\n",
      "隶属度矩阵初始化完成：shape= (3, 150)\n",
      "达到迭代次数，返回新的聚类中心和新的隶属度矩阵\n",
      "[0 1 2]\n",
      "(array([ 50,  51,  52,  54,  56,  58,  65,  68,  72,  74,  75,  76,  77,\n",
      "        86,  87,  97, 100, 102, 103, 104, 105, 107, 108, 109, 110, 111,\n",
      "       112, 115, 116, 117, 118, 120, 122, 123, 124, 125, 126, 128, 129,\n",
      "       130, 131, 132, 133, 135, 136, 137, 139, 140, 141, 143, 144, 145,\n",
      "       146, 147, 148], dtype=int64),)\n",
      "(array([  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,\n",
      "        13,  15,  16,  17,  19,  20,  21,  22,  23,  24,  25,  26,  27,\n",
      "        28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,\n",
      "        41,  42,  43,  44,  45,  46,  47,  48,  49,  57,  59,  93,  98,\n",
      "       106], dtype=int64),)\n",
      "(array([ 14,  18,  53,  55,  60,  61,  62,  63,  64,  66,  67,  69,  70,\n",
      "        71,  73,  78,  79,  80,  81,  82,  83,  84,  85,  88,  89,  90,\n",
      "        91,  92,  94,  95,  96,  99, 101, 113, 114, 119, 121, 127, 134,\n",
      "       138, 142, 149], dtype=int64),)\n",
      "[1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1\n",
      " 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 2 0 2 0 1 0 1 2 2 2 2 2 0 2 2 0 2 2 2 0 2\n",
      " 0 0 0 0 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 1 2 2 2 0 1 2 0 2 0 0 0 0 1 0 0 0 0\n",
      " 0 0 2 2 0 0 0 0 2 0 2 0 0 0 0 0 2 0 0 0 0 0 0 2 0 0 0 2 0 0 0 2 0 0 0 0 0\n",
      " 0 2]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import load_iris\n",
    "X,y=load_iris(return_X_y=True)\n",
    "\n",
    "# 只取两个特征，便于可视化\n",
    "X=X[:,:2]\n",
    "print(\"数据集：shape\",X.shape)\n",
    "\n",
    "C=3\n",
    "\n",
    "c,fuzzy_matrix=fuzzy_k_means(X=X,C=C,epsilon=0.1,iter_num=5,m=2)\n",
    "# 根据隶属度矩阵，将每列的最大值设为1，其余设为0\n",
    "classification_matrix=(fuzzy_matrix == fuzzy_matrix.max(axis=0, keepdims=0)).astype(float)\n",
    "# print(classification_matrix)      #输出判定后的结果\n",
    "\n",
    "# 根据判定结果划分类\n",
    "cm=np.array(range(C))\n",
    "print(cm)\n",
    "# 从classification_matrix中按cm中元素的顺序找到c所指定的行，然后再这些行中发现值为1的位置。\n",
    "# print(np.where(classification_matrix[cm]==1)) # 返回指定行的指定元素的位置索引 这里返回了b[c]每行中 值为1的位置索引\n",
    "# print(np.where(classification_matrix[cm]==1))\n",
    "\n",
    "y_lable=deepcopy(y)\n",
    "\n",
    "for row in range(C):\n",
    "    print(np.where(classification_matrix[row]==1))\n",
    "    class_index=np.where(classification_matrix[row]==1)\n",
    "    for index in class_index:\n",
    "        y_lable[index]=row\n",
    "\n",
    "print(y_lable)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 绘图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 864x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 支持中文\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号\n",
    "\n",
    "\n",
    "fig=plt.figure(figsize=(12,8))\n",
    "\n",
    "plt.scatter(X[:,0],X[:,1],c=y_lable)\n",
    "\n",
    "plt.scatter(c[:,0],c[:,1],marker='x')\n",
    "\n",
    "plt.show()\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "ef5d24e0d2c84d039f54e91090127d09d49c084eaee5cf0e1a1563975f8d1469"
  },
  "kernelspec": {
   "display_name": "Python 3.8.8 64-bit ('3.8.8')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
